package com.gitee.wsl.math.matrix


import kotlin.math.sqrt

class RowVector : MutableMatrix {
    /**
     * Constructor.
     *
     * @param n
     * the number of elements
     */
    constructor(n: Int) : super(1, n) {}

    /**
     * Constructor.
     *
     * @param values
     * the array of values
     */
    constructor(values: FloatArray) {
        set(values)
    }

    /**
     * Constructor.
     *
     * @param m
     * the matrix (only the first row used)
     */
    private constructor(m: MutableMatrix) {
        _set(m)
    }

    /**
     * @return the row vector's size.
     */
    fun size(): Int {
        return m_nCols
    }

    /**
     * Copy the values of this matrix.
     *
     * @return the copied values
     */
    fun copyValues1D(): FloatArray {
        val v = FloatArray(m_nCols)
        for (c in 0 until m_nCols) v[c] = m_aValues[0][c]
        return v
    }

    /**
     * Return the i'th value of the vector.
     *
     * @param i
     * the index
     * @return the value
     */
    fun at(i: Int): Float {
        return m_aValues[0][i]
    }

    /**
     * Set this row vector from a matrix. Only the first row is used.
     *
     * @param m
     * the matrix
     */
    private fun _set(m: MutableMatrix) {
        m_nRows = 1
        m_nCols = m.m_nCols
        m_aValues = m.m_aValues
    }

    /**
     * Set this row vector from an array of values.
     *
     * @param values
     * the array of values
     */
    protected fun set(values: FloatArray) {
        m_nRows = 1
        m_nCols = values.size
        m_aValues = Array(1){ FloatArray(1) }
        m_aValues[0] = values
    }

    /**
     * Set the i'th value of the vector.
     *
     * @param i
     * the index
     * @param value
     * the value
     */
    operator fun set(i: Int, value: Float) {
        m_aValues[0][i] = value
    }
    // -------------------//
    // Vector operations //
    // -------------------//
    /**
     * Add another row vector to this row vector.
     *
     * @param rv
     * the other row vector
     * @return the sum row vector
     * @throws MatrixException
     * for invalid size
     */
    @Throws(MatrixException::class)
    fun add(rv: RowVector): RowVector {
        return RowVector(super.add(rv))
    }

    /**
     * Subtract another row vector from this row vector.
     *
     * @param rv
     * the other row vector
     * @return the sum row vector
     * @throws MatrixException
     * for invalid size
     */
    @Throws(MatrixException::class)
    fun subtract(rv: RowVector): RowVector {
        return RowVector(super.subtract(rv))
    }

    /**
     * Compute the Euclidean norm.
     *
     * @return the norm
     */
    fun norm(): Float {
        var t = 0.0f
        for (c in 0 until m_nCols) {
            val v: Float = m_aValues[0][c]
            t += (v * v)
        }
        return sqrt(t)
    }



    /**
     * Print the vector values.
     *
     * @param aPS
     * the print stream to write on. May not be `null`.
     */
    /*fun print(aPS: PrintStream) {
        for (c in 0 until m_nCols) {
            aPS.print("  " + m_aValues[0][c])
        }
        aPS.println()
    }*/
}